package chen.web.back.client;

import java.util.Iterator;
import java.util.Set;

import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.KeyListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.Status;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;

public class LoginDialog extends Dialog{

	private TextField<String> nickname;
	private TextField<String> password;
	private Button reset;
	private Button login;
	private Status status;
	private Label errorMsgLabel;

	LoginDialog() {
		super();
		errorMsgLabel = new Label();
		errorMsgLabel.setVisible(false);
		this.add(errorMsgLabel);
		
		
		FormLayout layout = new FormLayout();
		layout.setLabelWidth(70);
		layout.setDefaultWidth(155);
		this.setLayout(layout);

		this.setButtonAlign(HorizontalAlignment.LEFT);
		this.setButtons("");
		this.setIcon(IconHelper.createStyle("user"));
		this.setHeading("登录");
		this.setModal(true);
		this.setBodyBorder(true);
		this.setBodyStyle("padding:8px;background: none");
		this.setWidth(300);
		this.setResizable(false);

		KeyListener keyListener = new KeyListener() {
			public void componentKeyUp(ComponentEvent event) {
				validate();
			}

		};

		nickname = new TextField<String>();
		nickname.setMinLength(4);
		nickname.setFieldLabel("用户名");
		nickname.addKeyListener(keyListener);
		nickname.setLabelStyle("text-align:right; margin-right:20px;");
		this.add(nickname);

		password = new TextField<String>();
		password.setMinLength(4);
		password.setPassword(true);
		password.setFieldLabel("密码");
		password.setLabelStyle("text-align:right; margin-right:20px;");
		password.addKeyListener(keyListener);
		this.add(password);

		this.setFocusWidget(nickname);
		this.setClosable(false);

		status = new Status();
		status.setBusy("please wait...");
		status.hide();
		status.setAutoWidth(true);
		this.getButtonBar().add(status);
		this.getButtonBar().add(new FillToolItem());

		reset = new Button("重置");
		reset.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				nickname.reset();
				password.reset();
				validate();
				nickname.focus();
			}

		});

		login = new Button("登录");
		login.disable();
		login.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				onSubmit();
			}
		});

		this.addButton(reset);
		this.addButton(login);
	}

	private void onSubmit() {
		status.show();
		this.getButtonBar().disable();
		RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, UrlHelper.toAbsolute("/login"));
		builder.setHeader("Content-Type", "application/json");
		try {
			FormDataBuilder fdb = new FormDataBuilder();
			fdb.addProperty("nickname", nickname.getValue())
					.addProperty("password", password.getValue());
			builder.sendRequest(fdb.toJSONString(), new RequestCallback() {
				public void onError(Request request, Throwable exception) {
					displayError("Couldn't retrieve JSON");
				}

				@Override
				public void onResponseReceived(Request request,
						Response response) {
					// TODO Auto-generated method stub
					if (200 == response.getStatusCode()) {
						process(response);
					} else {
						displayError("Couldn't retrieve JSON ("
								+ response.getStatusText() + ")");
					}
				}
			});
		} catch (RequestException e) {
			displayError("Couldn't retrieve JSON");
		}
	}

	private void process(Response response) {
		status.hide();
		JSONValue json = JSONParser.parseStrict(response
				.getText());
		JSONValue process = json.isObject().get("success");
		if (process != null && process.isBoolean().booleanValue()) {
			Cookies.setCookie("login", Boolean.toString(true));
			this.hide();
			Window.Location.reload();
		} else {
			JSONValue errors = json.isObject().get("errors");
			JSONArray array = errors.isArray();
			for(int i=0; i<array.size(); i++){
				String element = array.get(i).isObject().get("element").isString().stringValue();
				String message = array.get(i).isObject().get("message").isString().stringValue();
				if("nickname".equals(element)){
					nickname.markInvalid(message);
				} else if("password".equals(element)){
					password.markInvalid(message);
				} else {
					displayError(message);
				}
			}
		}
		this.getButtonBar().enable();
	}

	private void displayError(String message) {
		status.hide();
		errorMsgLabel.setText(message);
	}

	private boolean hasValue(TextField<String> field) {
		return field.getValue() != null && field.getValue().length() > 0;
	}

	private void validate() {
		login.setEnabled(hasValue(nickname) && hasValue(password)
				&& password.getValue().length() > 3);
	}
	
	public static boolean checkLogin(){
		if(!Boolean.parseBoolean(Cookies.getCookie("login"))){
			LoginDialog dialog = new LoginDialog();
			dialog.show();
			return false;
		}
		return true;
	}

}
